/**
 * 文件名称: auth-manager.js
 * 完整存储路径: frontend/static/js/auth-manager.js
 * 功能说明:
 *     全局认证处理模块，统一处理token过期、自动跳转登录等认证相关功能
 *     解决PC端系统管理模块token过期时的用户体验问题，实现无缝重新认证
 *     
 * 主要功能:
 *     - 统一的API请求认证处理（AuthManager.authenticatedFetch）
 *     - Token过期自动检测和处理（监听401响应）
 *     - 登录模态框动态创建和管理
 *     - 登录成功后自动重新执行原请求
 *     - 保持页面状态，避免跳转刷新
 *     
 * 使用方法:
 *     替换所有fetch调用为AuthManager.authenticatedFetch()
 *     
 * 技术规范依据:
 *     按照《文档C：技术实现规范》统一认证架构设计
 *     遵循《文档B：业务标准规范》JWT认证标准
 *     
 * 创建日期: 2025-08-28
 * 最后修改: 2025-08-28
 * 修改原因: 解决PC端管理模块token过期导致的401错误和用户体验问题
 */

// 全局认证对象
window.AuthManager = {
    // 当前页面URL，用于登录后跳转回来
    currentPage: window.location.pathname + window.location.search,
    
    // 活动续期相关配置
    lastActivity: Date.now(),
    renewalTimer: null,
    renewalInterval: 2 * 60 * 1000, // 2分钟检查一次是否需要续期
    inactivityTimeout: 5 * 60 * 1000, // 5分钟无活动超时
    
    /**
     * 初始化活动监听和自动续期
     */
    initActivityTracking: function() {
        // 监听用户活动事件
        const activityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];
        
        const updateActivity = () => {
            this.lastActivity = Date.now();
        };
        
        // 绑定所有活动事件
        activityEvents.forEach(event => {
            document.addEventListener(event, updateActivity, true);
        });
        
        // 启动定期检查
        this.startRenewalTimer();
    },
    
    /**
     * 启动token续期定时器
     */
    startRenewalTimer: function() {
        if (this.renewalTimer) {
            clearInterval(this.renewalTimer);
        }
        
        this.renewalTimer = setInterval(() => {
            const now = Date.now();
            const timeSinceActivity = now - this.lastActivity;
            
            // 如果用户有活动且token存在，进行续期
            if (timeSinceActivity < this.inactivityTimeout && this.isLoggedIn()) {
                this.renewToken();
            } else if (timeSinceActivity >= this.inactivityTimeout && this.isLoggedIn()) {
                // 超过5分钟无活动，清除token并重定向到登录页
                console.log('用户无活动超过5分钟，自动登出');
                this.clearToken();
                window.location.href = '/login';
            }
        }, this.renewalInterval);
    },
    
    /**
     * 续期token
     */
    renewToken: function() {
        if (!this.isLoggedIn()) return;
        
        fetch('/api/auth/renew', {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${this.getToken()}`,
                'Content-Type': 'application/json'
            }
        })
        .then(response => response.json())
        .then(data => {
            if (data.success && data.access_token) {
                // 更新token
                localStorage.setItem('access_token', data.access_token);
                document.cookie = "access_token=" + data.access_token + "; path=/";
                console.log('Token续期成功');
            }
        })
        .catch(error => {
            console.warn('Token续期失败:', error);
        });
    },
    
    /**
     * 检查用户是否已登录
     * @returns {boolean} 如果已登录返回true，否则返回false
     */
    isLoggedIn: function() {
        const token = localStorage.getItem('access_token');
        return token && token.trim() !== '';
    },
    
    /**
     * 获取当前存储的访问token
     * @returns {string|null} 访问token或null
     */
    getToken: function() {
        return localStorage.getItem('access_token');
    },
    
    /**
     * 清除存储的token（用于登出）
     */
    clearToken: function() {
        localStorage.removeItem('access_token');
        document.cookie = "access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
    },
    
    /**
     * 显示登录模态框，支持回调函数
     * @param {function} callback 登录成功后的回调函数
     */
    showLoginModal: function(callback) {
        // 如果页面上没有登录模态框，创建一个
        if (!document.getElementById('globalLoginModal')) {
            this.createLoginModal();
        }
        
        // 保存回调函数
        this.loginSuccessCallback = callback;
        
        // 显示模态框
        const modal = new bootstrap.Modal(document.getElementById('globalLoginModal'));
        modal.show();
    },
    
    /**
     * 动态创建登录模态框HTML结构
     * 使用Bootstrap 5组件，包含用户名密码输入框和登录按钮
     */
    createLoginModal: function() {
        const modalHtml = `
        <div class="modal fade" id="globalLoginModal" tabindex="-1" aria-labelledby="globalLoginModalLabel" aria-hidden="true" data-bs-backdrop="static">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="globalLoginModalLabel">
                            <i class="bi bi-lock"></i> 重新登录
                        </h5>
                    </div>
                    <div class="modal-body">
                        <div id="globalLoginAlert"></div>
                        <form id="globalLoginForm">
                            <div class="mb-3">
                                <label for="globalUsername" class="form-label">用户名</label>
                                <input type="text" class="form-control" id="globalUsername" required>
                            </div>
                            <div class="mb-3">
                                <label for="globalPassword" class="form-label">密码</label>
                                <input type="password" class="form-control" id="globalPassword" required>
                            </div>
                        </form>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-primary" id="globalLoginBtn" onclick="AuthManager.doLogin()">
                            <i class="bi bi-box-arrow-in-right"></i> 登录
                        </button>
                    </div>
                </div>
            </div>
        </div>
        `;
        
        // 添加到页面
        document.body.insertAdjacentHTML('beforeend', modalHtml);
    },
    
    /**
     * 执行登录操作
     * 调用/api/auth/login接口，成功后保存token并执行回调
     */
    doLogin: function() {
        const username = document.getElementById('globalUsername').value;
        const password = document.getElementById('globalPassword').value;
        
        if (!username || !password) {
            this.showLoginAlert('请输入用户名和密码', 'danger');
            return;
        }
        
        const loginBtn = document.getElementById('globalLoginBtn');
        loginBtn.disabled = true;
        loginBtn.innerHTML = '<i class="bi bi-arrow-clockwise spin"></i> 登录中...';
        
        fetch('/api/auth/login', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                username: username,
                password: password
            })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success && data.access_token) {
                // 保存token
                localStorage.setItem('access_token', data.access_token);
                document.cookie = "access_token=" + data.access_token + "; path=/";
                
                // 关闭模态框
                bootstrap.Modal.getInstance(document.getElementById('globalLoginModal')).hide();
                
                // 执行回调函数
                if (typeof this.loginSuccessCallback === 'function') {
                    this.loginSuccessCallback();
                }
                
                this.showLoginAlert('登录成功', 'success');
            } else {
                this.showLoginAlert('登录失败: ' + (data.message || '未知错误'), 'danger');
            }
        })
        .catch(error => {
            console.error('Login error:', error);
            this.showLoginAlert('网络错误，请重试', 'danger');
        })
        .finally(() => {
            loginBtn.disabled = false;
            loginBtn.innerHTML = '<i class="bi bi-box-arrow-in-right"></i> 登录';
        });
    },
    
    /**
     * 在登录模态框中显示提示信息
     * @param {string} message 提示消息
     * @param {string} type Bootstrap alert类型（success, danger, warning等）
     */
    showLoginAlert: function(message, type) {
        const alertDiv = document.getElementById('globalLoginAlert');
        alertDiv.innerHTML = `
            <div class="alert alert-${type} alert-dismissible fade show" role="alert">
                ${message}
                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            </div>
        `;
    },
    
    /**
     * 增强的fetch函数，自动处理401错误和token认证
     * 这是本模块的核心功能，替代原生fetch调用
     * 
     * @param {string} url 请求URL
     * @param {object} options fetch选项对象
     * @returns {Promise} fetch Promise，会自动处理认证
     * 
     * 功能特性:
     * - 自动添加Authorization header
     * - 检测401响应并自动显示登录框
     * - 登录成功后自动重新执行原请求
     * - 保持原有的Promise链式调用方式
     * - 提供友好的Token过期提示
     */
    authenticatedFetch: function(url, options = {}, originalFetch = null) {
        // 确保headers存在
        options.headers = options.headers || {};
        
        // 添加Authorization header
        const token = this.getToken();
        if (token) {
            options.headers['Authorization'] = `Bearer ${token}`;
        }

        // 如果没有传入originalFetch，使用原生fetch
        const fetchFn = originalFetch || fetch.bind(window);
        
        return fetchFn(url, options)
            .then(response => {
                // 如果是401错误，显示友好的Token过期提示
                if (response.status === 401) {
                    // 清理本地存储
                    localStorage.removeItem('access_token');
                    localStorage.removeItem('login_time');
                    
                    return new Promise((resolve, reject) => {
                        // 显示友好的Token过期提示
                        this.showTokenExpiredDialog(() => {
                            // 登录成功后重新请求
                            options.headers['Authorization'] = `Bearer ${this.getToken()}`;
                            fetchFn(url, options).then(resolve).catch(reject);
                        });
                    });
                }
                return response;
            })
            .catch(error => {
                // 网络错误等情况，直接抛出错误，不显示JSON
                console.error('API请求失败:', error);
                throw error;
            });
    },

    /**
     * 显示Token过期提示对话框
     * @param {function} loginSuccessCallback 登录成功后的回调函数
     */
    showTokenExpiredDialog: function(loginSuccessCallback) {
        // 显示确认对话框
        if (confirm('登录过期，请重新登录')) {
            // 用户点击确认，显示登录模态框
            this.showLoginModal(loginSuccessCallback);
        } else {
            // 用户点击取消，跳转到登录页面
            window.location.href = '/';
        }
    },

    /**
     * 全局fetch拦截器，替换原生fetch以提供统一的认证处理
     * 这个方法会覆盖window.fetch，使所有fetch调用都经过认证处理
     */
    initGlobalFetchInterceptor: function() {
        // 保存原生fetch的绑定版本和this引用
        const originalFetch = window.fetch.bind(window);
        const self = this;
        
        // 覆盖全局fetch
        window.fetch = (url, options = {}) => {
            // 检查是否是需要认证的API请求
            if (typeof url === 'string' && url.startsWith('/api/') && !url.includes('/api/auth/login') && !url.includes('/api/auth/register')) {
                // 使用AuthManager的authenticatedFetch处理需要认证的API请求，传入原生fetch
                return self.authenticatedFetch(url, options, originalFetch);
            }
            
            // 对于非API请求或登录/注册请求，使用原生fetch
            return originalFetch(url, options);
        };
        
        console.log('Global fetch interceptor initialized');
    }
};

// 添加CSS样式
const style = document.createElement('style');
style.textContent = `
    .spin {
        animation: spin 1s linear infinite;
    }
    
    @keyframes spin {
        from { transform: rotate(0deg); }
        to { transform: rotate(360deg); }
    }
`;
document.head.appendChild(style);

// 页面加载完成后的初始化
document.addEventListener('DOMContentLoaded', function() {
    // 初始化全局fetch拦截器
    AuthManager.initGlobalFetchInterceptor();
    
    // 初始化活动追踪和自动续期
    AuthManager.initActivityTracking();
    
    console.log('AuthManager initialized with global fetch interceptor and activity tracking');
});
